时间片,上下文,调度算法等知识点~
嘿嘿 小伙伴们好久不见啦~ 我又回来啦!😝
很久很久以前,有一个小伙子说了下篇要讲这个~ (幸好记下了 哈哈 不然我都不知道写到哪去了 (((φ(◎ロ◎;)φ))) )
时间片
❝「时间片」(timeslice)又称为“量子(quantum)” 或 “处理器片(processor slice)” 是 「分时操作系统」 分配给每个正在运行的进程微观上的一段CPU时间(在抢占内核中是:从进程开始运行直到被抢占的时间)。
时间片由 操作系统内核 的 调度程序 分配给每个进程。首先,内核会给每个进程分配相等的初始时间片,然后每个进程轮番地执行相应的时间,当所有进程都处于时间片耗尽的状态时,内核会重新为每个进程计算并分配时间片,如此往复 ——《百度百科》
❞
简单来说就是将 CPU的运行时间切分出来,分配给不同的程序去运行~ 😋
进程调度算法
如下~
这里简单介绍下这个 「先来先服务」, 「短作业」 和 「时间片轮转」 ~
小伙伴们可以大致了解下~
先来先服务(FCFS)
CPU 从就绪队列中获取最早进入该队列的进程,为其分配 CPU 资源并运行
短作业
每次运行时从队列中选一个预估运行时间最短的 , 可提高 CPU 整体的利用率和系统运行效率, 会导致某些大任务 长时间得不到调度
时间片轮转
按照 先来先服务 原则,从就绪队列中取出一个任务,并为其分配一定的 CPU 时间片去运行, 使用完时间片后由一个「时间计数器」发出 时钟中断请求,「调度器」在收到时钟中断请求后,停止该进程,并将它放到就绪队列的 「队尾」,接着从 「队首」 取出一个任务并为其分配 CPU 时间片去运行
上下文
经常听到的就是上下文切换~ 还有 Spring 的上下文之间,应用上下文 等等~
还有 这位同学,请你结合上下文,回答下面这个问题:“朱自清的《背影》:我买几个橘子去。你就在此地,不要走动。” 中买橘子是啥意思?
哈哈哈~ 不知道小伙伴有没有悟到呢 ,买橘子中,「结合上下文」,我们可以很快明白就是 在这篇文章中查找信息~
而程序中的上下文,无非就是程序的运行环境,比如
进程/线程 的上下文切换
❝上下文切换指的是 「内核(操作系统的核心)在 CPU 上对进程或者线程进行切换」 。上下文「切换过程中的信息被保存在进程控制块」(PCB-Process Control Block)中。PCB 又被称作切换帧(SwitchFrame)。上下文切换的信息会一直被保存在CPU的内存中,直到被再次使用 ——《百度百科》
❞
Spring 的上下文 ApplicationContext
我们在使用 Springboot
的时候,经常需要去获取 Spring
的上下文 ApplicationContext
来获取 Spring
容器创建的对象呀,配置信息等~
比如这样子~
/**
* @author 公众号:Java4ye
*/
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if(SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
//获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过name获取 Bean.
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name,Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
}
使用时就可以通过这样获取到 Spring
容器管理的对象了~
A a = SpringUtil.getBean(A.class);
这里的上下文可以理解为 Spring 的容器环境~ 😄
咳咳~ 插个题外话~
怎么将对象交给 Spring 容器管理呢?
哈哈哈 这里简单带过一下~
@Bean
注解实现 BeanFactoryPostProcessor
接口 (这可是把牛刀!~ 咳咳 后面 讲 Spring 再带上~ 坑🕳😝)
xml 就不说啦,老古董的方式了
咳咳 不唠嗑了 说完最后一点赶紧好好写线程了😂 (知识点咋那么多呀)
进程,线程,协程
关系如图:
「进程 是 操作系统分配和调度的基本单位」
「线程 是 操作系统调度的最小单元」
每个进程中至少有一个线程在运行!
为什么要设计出线程呢?
肯定是进程有大缺点啦 😄 比如
并发 ,我们知道进程都有自己独立的内存空间,这样的话多进程之间数据的同步就变得很麻烦啦 创建和销毁进程的开销特别大,看上图就可以发现啦~(那么多东西)
为了减少系统开销,就有了这个线程啦,可以看到线程之间相互隔离,但是共享进程中的资源 ,可以解决数据同步问题
那为啥还要设计协程呢?
线程虽然比进程少了很大部分的开销,但是仍然有它的问题
比如
线程的创建和销毁
线程的切换开销
其实这个在 Java 里已经有很成熟的解决办法啦 ~ 「线程池」 ,「Netty」
线程这个小家伙,外号 「轻量级进程」 , 它有自己的 堆栈,程序计数器,寄存器等 不共享的信息~ 😄
如果数量过多的话,不仅仅会有内存上的压力,他们之间的竞争带来的系统开销也是一个大问题!
而在当今 「高并发」 时代~ ,还有没有更灵活的方式来提高系统的并发量呢?
当然有,这就是到协程的登场啦!
协程又称 👉 「用户态线程」,没有上下文切换等系统开销,效率非常高!
而且占用内存非常少,线程是 MB 级别的,而它是 KB 级别的
后面再多做些调研再和大家分享这个协程~ 😝
总结
最近讲的知识点 大致如下 😝
下篇正式进入线程啦~ 😝
下期见啦各位!😝
带你从CPU看到进程~(硬核)
Java中的锁居然有这么多!
我理清楚要怎么写并发啦~ (小思考)
终于来到 ConcurrentHashMap 了~
谢谢可爱又帅气的大佬们的观看!祝您 天天开心!😄
感谢您的关注!您的每个关注,都是博主 肝肝肝的动力 😝